﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.VisualBasic.FileIO;
using Microsoft.Win32;
using MkLink;
using SymbolicLinkManageCore;
using SymbolicLinkManageCore.Exceptions;
using SymbolicLinkManageCore.Library.UsersAndPermissions;
using SymbolicLinkManageUI.Library;
using SymbolicLinkManageUI.windows;
using SymbolicLinkManageUI.Windows;
using UtilityToolsCollectInStandard;
using UtilityToolsCollectInStandard.ToolsCollection;


namespace SymbolicLinkManageUI.Lib
{
    public partial class MainWindowVM : ObservableObject
    {
        private MainWindow mainWindow;
        private CollectionViewSource? m_ListBoxViewSource;
        private CollectionViewSource? ListBoxViewSource 
        {
            get
            {
                if(m_ListBoxViewSource == null)
                {
                    if (mainWindow == null)
                        return null!;
                    m_ListBoxViewSource = (CollectionViewSource)mainWindow.Resources["ListVS"];
                }
                return m_ListBoxViewSource;
            }
          }

        private ICollectionView? m_ListBoxCollectionView;
        private ICollectionView? ListBoxCollectionView
        {
            get
            {
                if (m_ListBoxCollectionView == null)
                    m_ListBoxCollectionView = ListBoxViewSource?.View;
                return m_ListBoxCollectionView;
            }
        }
        public MainWindowVM() { mainWindow = null!; Config.Current.RecordDatas.CollectionChanged += RecordDatas_CollectionChanged;}
        public MainWindowVM(MainWindow mainWindow) { this.mainWindow = mainWindow; Config.Current.RecordDatas.CollectionChanged += RecordDatas_CollectionChanged; }

        private void RecordDatas_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            IsListCount = Config.Current.RecordDatas.Count >= 2;
            IsValidRecord = Config.Current.RecordDatas.Count > 0;
        }

        [ObservableProperty] private bool isScanComputer;
        [ObservableProperty, NotifyCanExecuteChangedFor(nameof(SetExpanderCommand))] private bool isListCount = true;
        [ObservableProperty, NotifyCanExecuteChangedFor(nameof(ValidRecordCommand))] private bool isValidRecord = true;
        [ObservableProperty, NotifyCanExecuteChangedFor(nameof(ValidRecordCommand), nameof(ReadListFormTextCommand),
            nameof(ScanComputerCommand),nameof(HardLinkResetCommand),nameof(Master_Slave_SwitchCommand))] private bool isBackgroundWork = false;
        private bool IsEnableButton => IsValidRecord && !IsBackgroundWork;
        private bool IsNotBackgroundWork => !IsBackgroundWork;
        private bool IsEnableButton_isListCount => IsEnableButton && IsListCount;
        
        [ObservableProperty, NotifyPropertyChangedFor(nameof(ProgressText))] private double m_Progress = 0;
        public string ProgressText => $"{Progress}%";

        [RelayCommand(CanExecute = nameof(IsNotBackgroundWork))] public async Task ReadListFormText()
        {
            if (!Tools.OpenFileDialog(mainWindow, "选择列表文件", "文本文档 (.text)|*.txt", "文本文档|*.txt", out string ResultPath))
                return;
            RecordData[] result = [];
            try { result = ManageCore.ReadPathsFormTxtFile(ResultPath); }
            catch (Exception exc) { LogManage.WriteExceptionInfo($"读取列表文件[{ResultPath}]错误:", exc, true); }
            if (result.Length < 1)
            {
                LogManage.WriteLineNewInfo($"读取列表文件[{ResultPath}] 无数据:", true);
                return;
            }
            SelectWindow selectWindow = new SelectWindow(result);
            if (!(selectWindow.ShowDialog() ?? false))
                return;
            await Task.Run(() => ManageCore.AddRecordDatas(selectWindow.selectLists));
        }


        [RelayCommand(CanExecute = "IsEnableButton", IncludeCancelCommand = true)] public async Task ScanComputerAsync(CancellationToken token)
        {
            IsBackgroundWork = true;
            try
            {
                SearchSettingsWindow searchSettingsWindow = new SearchSettingsWindow();
                if (!searchSettingsWindow.ShowDialog() ?? false)
                    return;
                RecordData[] recordDatas = [];

                Grid ProgressBarLayer = mainWindow.WaitProgressBarLayer;
                Button CanButton = mainWindow.ScanCance;
                ProgressBarLayer.Visibility = Visibility.Visible;
                CanButton.Visibility = Visibility.Visible;

                try
                {
                    recordDatas = await Task.Run(() => ManageCore.ScanComputer(token, searchSettingsWindow.Result, searchSettingsWindow.IsEnableHardLink,
                    p => { mainWindow.Dispatcher.BeginInvoke(() => { Progress = Math.Round(p, 3, MidpointRounding.ToZero); }); }));
                }
                catch (Exception exc) { LogManage.WriteExceptionInfo($"全扫描磁盘错误:", exc, true); }
                finally { ProgressBarLayer.Visibility = Visibility.Collapsed; CanButton.Visibility = Visibility.Collapsed; }

                if (recordDatas.Length < 1)
                {
                    LogManage.WriteLineNewInfo($"全扫描磁盘无结果", true);
                    return;
                }

                SelectWindow selectWindow = new SelectWindow(recordDatas);
                if (!(selectWindow.ShowDialog() ?? false))
                    return;
                await Task.Run(() => ManageCore.AddRecordDatas(selectWindow.selectLists));
            }
            finally { IsBackgroundWork = false; }
        }

        [RelayCommand(CanExecute = "IsEnableButton_isListCount")] public void Master_Slave_Switch() 
        {
            ManageCore.Master_Slave_ShowSwitch();
            mainWindow.ListBoxView.LayoutUpdated += ListBoxView_LayoutUpdated;
            ListBoxCollectionView?.Refresh(); 
        }
        private void ListBoxView_LayoutUpdated(object? sender, EventArgs e) { mainWindow.ListBoxView.LayoutUpdated -= ListBoxView_LayoutUpdated; SetExpander(CurrentIsExpanded); }

        
        private bool CurrentIsExpanded = false;
        [RelayCommand(CanExecute = "IsEnableButton_isListCount")] public void SetExpander(bool IsExpanded) { CurrentIsExpanded = IsExpanded; XamlUtilityTools.GetChilds<Expander>(mainWindow.ListBoxView).ForEach(p => p.IsExpanded = IsExpanded);}


        [RelayCommand(CanExecute = "IsEnableButton")] public async Task ValidRecord()
        {
            IsBackgroundWork = true;
            try
            {
                await Task.Run(() =>
                {
                   var Duplicates = ManageCore.GetDuplicates(Config.Current.RecordDatas).ToArray();

                    if (Duplicates != null && Duplicates.Length > 0)
                    {
                        foreach (RecordData item in Duplicates)
                            mainWindow.Dispatcher.BeginInvoke(() => Config.Remove(item), System.Windows.Threading.DispatcherPriority.DataBind);
                        _ = Task.Run(() => Config.Save());
                    }
                }).ContinueWith(t => { Task.Delay(2000).Wait(); Config.Current.RecordDatas.ForEach(p => p.ValidRecord()); });
            }
            finally { IsBackgroundWork = false; }
        }

        [RelayCommand(CanExecute = "IsEnableButton")] public async Task HardLinkReset()
        {
            IsBackgroundWork = true;
            try
            {
                (RecordData[] HardLinkData, RecordData[] result) result = await ManageCore.HardLinkDataRefactor(Config.Current.RecordDatas);
                foreach (RecordData data in result.HardLinkData)
                    Config.Remove(data);
                foreach (RecordData data in result.result)
                    Config.Add(data);
                _ = Task.Run(Config.Save);
            }
            finally { IsBackgroundWork = false; }
        }

        private bool GetSelectedItem(out RecordData result)
        {
            result = null!;
            object? item = mainWindow.ListBoxView.SelectedItem;
            if (item != null && item is RecordData recordData)
            {
                result = recordData;
                return true;
            }
            return false;
        }

        private Span<RecordData> CurrentSelectedRecordDatas => mainWindow.ListBoxView.SelectedItems.Cast<RecordData>().ToArray();

        [RelayCommand] public void CopyPath(bool IsLinkPointPath)
        {
            StringBuilder sb = new();
            if (IsLinkPointPath)
            {
                foreach (ref readonly RecordData item in CurrentSelectedRecordDatas)
                    if (!string.IsNullOrEmpty(item.LinkPointPath))
                        sb.AppendLine(item.LinkPointPath);
            }
            else
            {
                foreach (ref readonly RecordData item in CurrentSelectedRecordDatas)
                    if (!string.IsNullOrEmpty(item.LinkTargetPath))
                        sb.AppendLine(item.LinkTargetPath);
            }
            Clipboard.SetText(sb.ToString());
        }

        [RelayCommand] public void OpenExplorerTo(bool IsLinkPointPath)
        {
            if (!GetSelectedItem(out RecordData recordData))
                return;
            if (IsLinkPointPath)
                Tools.Explorer(recordData.LinkPointPath, true);
            else if (!string.IsNullOrWhiteSpace(recordData.LinkTargetPath))
                Tools.Explorer(recordData.LinkTargetPath, true);
            else MessageBoxEx.Show(mainWindow, "拷贝无效，无有效数据", "拷贝无效", MessageBoxButton.OK, MessageBoxImage.Error);
        }

        private bool RemoveOrDelConfirmCancel(string message, string Title) => MessageBoxEx.Show(mainWindow, message, Title, MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel) == MessageBoxResult.Cancel;

        [RelayCommand] public void Remove()
        {
            if (RemoveOrDelConfirmCancel("确认移除该条记录么？", "移除记录确认"))
                return;
            if (!GetSelectedItem(out RecordData recordData))
                return;
            Config.Remove(recordData);
            Config.Save();
        }

        [RelayCommand] public void RemoveSelects()
        {
            if (RemoveOrDelConfirmCancel("确认移除全部选中的记录么？", "移除记录确认"))
                return;
            foreach(ref readonly RecordData recordData in CurrentSelectedRecordDatas)
                Config.Remove(recordData);
            Config.Save();
        }

        [RelayCommand] public void RemoveAll()
        {
            if (RemoveOrDelConfirmCancel("确认移除全部记录么？", "移除记录确认"))
                return;
            Config.Clear();
            Config.Save();
        }

        [RelayCommand] public void Delete()
        {
            if (RemoveOrDelConfirmCancel("从磁盘上删除连接点后不可恢复，确认从磁盘上删除该连接点么？", "连接点删除确认"))
                return;
            if (!GetSelectedItem(out RecordData recordData))
                return;
            if (recordData.pathType == PathType.FileType)
                FileSystem.DeleteFile(recordData.LinkPointPath, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
            else if (recordData.pathType == PathType.DirectoryType)
                FileSystem.DeleteDirectory(recordData.LinkPointPath, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
            Config.Remove(recordData);
            Config.Save();
        }

        [RelayCommand] public void DeleteSelects()
        {
            if (RemoveOrDelConfirmCancel("从磁盘上删除连接点后不可恢复，确认从磁盘上删除全部选中的连接点么？", "连接点删除确认"))
                return;
            foreach (ref readonly RecordData recordData in CurrentSelectedRecordDatas)
            {
                Config.Remove(recordData);
                if (!Path.Exists(recordData.LinkPointPath))
                    continue;
                if (recordData.pathType == PathType.FileType)
                    FileSystem.DeleteFile(recordData.LinkPointPath, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
                else if (recordData.pathType == PathType.DirectoryType)
                    FileSystem.DeleteDirectory(recordData.LinkPointPath, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
            }
            Config.Save();
        }

        [RelayCommand] public void HardLinkCopyPath(ListBox CurrentSelect)
        {
            RecordData data = (RecordData)CurrentSelect.DataContext;
            HardLinkData[] Select = CurrentSelect.SelectedItems.Cast<HardLinkData>().ToArray();
            StringBuilder sb = new(); Select.ForEach(F => sb.AppendLine(F.FilePath));
            Clipboard.SetText(sb.ToString());
        }
        [RelayCommand] public void HardLinkOpenExplorerTo(ListBox CurrentSelect)
        {
            string? path = CurrentSelect.SelectedItem?.ToString();
            if (string.IsNullOrEmpty(path) || !File.Exists(path))
            {
                MessageBoxEx.Show(mainWindow, $"文件[{path}]不存在", "导航失败", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            Tools.Explorer(path, true);
        }
        private void CheckRemaining(RecordData data)
        {
            if (data.HardLinkGroup?.Count < 1)
                Config.Remove(data);
            else if (data.HardLinkGroup?.Count < 2)
            {
                if (RemoveOrDelConfirmCancel($"当前硬链接组仅剩[{data.HardLinkGroup!.First()}]，是否同时完全移除记录项？", "操作确认"))
                    return;
                Config.Remove(data);
            }
        }
        [RelayCommand] public void HardLinkRemove(ListBox CurrentSelect)
        {
            RecordData data = (RecordData)CurrentSelect.DataContext;
            HardLinkData Select = (HardLinkData)CurrentSelect.SelectedItem;
            //if(Select==null)
            //{
            //    LogManage.WriteExceptionInfo($"从[{data.LinkTargetPath}]的组中\r\n[\r\n{data.HardLinkGroupString}\r\n]，移除硬链接记录错误:",
            //        new NullReferenceException($"当前[{typeof(ListBox)}].[{nameof(CurrentSelect.SelectedItem)}]，返回了一个[Null]值"));
            //    return;
            //}
            data.HardLinkGroup?.Remove(Select);
            CheckRemaining(data);
            Config.Save();
        }
        [RelayCommand] public void HardLinkRemoveSelects(ListBox CurrentSelect)
        {
            RecordData data = (RecordData)CurrentSelect.DataContext;
            HardLinkData[] Select = (HardLinkData[])CurrentSelect.SelectedItems;
            StringBuilder sb = new(); Select.ForEach(F => sb.AppendLine(F.FilePath));
            if (RemoveOrDelConfirmCancel($"选中的记录：\r\n[\r\n{sb}\r\n]\r\n 确认移除选中的记录么？", "操作确认"))
                return;
            foreach (HardLinkData item in Select)
                data.HardLinkGroup?.Remove(item);
            CheckRemaining(data);
            Config.Save();
        }
        [RelayCommand] public void HardLinkRemoveAll(ListBox CurrentSelect)
        {
            RecordData data = (RecordData)CurrentSelect.DataContext;
            StringBuilder sb = new(); data.HardLinkGroup?.ForEach(F => sb.AppendLine(F.FilePath));
            if (RemoveOrDelConfirmCancel($"全部记录条目：\r\n[\r\n{sb}\r\n]\r\n 确认全部移除这些记录么？", "操作确认"))
                return;
            Config.Remove(data);
            Config.Save();
        }
        [RelayCommand] public void HardLinkDelete(ListBox CurrentSelect)
        {
            RecordData data = (RecordData)CurrentSelect.DataContext;
            HardLinkData Select = (HardLinkData)CurrentSelect.SelectedItem;
            if (!File.Exists(Select.FilePath))
            {
                data.HardLinkGroup?.Remove(Select);
                return;
            }
            if (RemoveOrDelConfirmCancel($"执行删除文件[{data.HardLinkGroup!.First()}]操作，该操作将彻底删除文件，删除后不可恢复，是否确认删除该文件？", "操作确认"))
                return;
            FileSystem.DeleteFile(Select.FilePath, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
            data.HardLinkGroup?.Remove(Select);
            CheckRemaining(data);
            Config.Save();
        }
        [RelayCommand] public void HardLinkDeleteSelects(ListBox CurrentSelect)
        {
            RecordData data = (RecordData)CurrentSelect.DataContext;
            HardLinkData[] Select = (HardLinkData[])CurrentSelect.SelectedItems;

            IEnumerable<IGrouping<bool, HardLinkData>> SelectGruop = Select.GroupBy(p => File.Exists(p.FilePath));
            HardLinkData[]? hlFile = SelectGruop.FirstOrDefault(p => p.Key)?.ToArray() ?? [];

            SelectGruop.FirstOrDefault(p => !p.Key)?.ForEach(p => data.HardLinkGroup?.Remove(p));

            StringBuilder sb = new();
            hlFile.ForEach(p => sb.AppendLine(p));
            
            if (RemoveOrDelConfirmCancel($"执行删除文件\r\n[\r\n{sb}\r\n]\r\n操作，该操作将彻底删除文件，删除后不可恢复，是否确认删除该文件？", "操作确认"))
                return;

            foreach (HardLinkData item in hlFile)
                FileSystem.DeleteFile(item.FilePath, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
            CheckRemaining(data);
            Config.Save();
        }
        [RelayCommand] public void HardLinkDeleteAll(ListBox CurrentSelect)
        {
            RecordData data = (RecordData)CurrentSelect.DataContext;
            HardLinkData[] hlFile = data.HardLinkGroup?.Where(p => File.Exists(p)).ToArray() ?? [];
            StringBuilder sb = new();
            hlFile.ForEach(p => sb.AppendLine(p));

            if (RemoveOrDelConfirmCancel($"执行删除文件\r\n[\r\n{sb}\r\n]\r\n操作，该操作将彻底删除文件，删除后不可恢复，是否确认删除该文件？", "操作确认"))
                return;

            foreach (HardLinkData item in hlFile)
                FileSystem.DeleteFile(item.FilePath, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
            Config.Remove(data);
            Config.Save();
        }
        [RelayCommand(CanExecute = nameof(IsSupportCreateTypeLinkType))] public void OpenPickPathWindow(bool IsLinkPoint)
        {
            if (IsLinkPoint)
            {
                if (!Tools.OpenNullFolderDialog(mainWindow, Environment.GetFolderPath(Environment.SpecialFolder.MyComputer), "连接点路径", "名称", out string ResultPath))
                    return;
                if (IsLinkPoint)
                    LinkPointPath = ResultPath;
                else LinkTargetPath = ResultPath;
            }
            else
            {
                if (!Tools.OpenFolderDialog(mainWindow, Environment.GetFolderPath(Environment.SpecialFolder.MyComputer), "选择要连接的目标",
                    CreateType == LinkType.SYMLINKD || CreateType == LinkType.JUNCTION, out string path))
                    return;
                if (IsLinkPoint)
                    LinkPointPath = path;
                else LinkTargetPath = path;
            }
        }
        [RelayCommand] public void OpenLogWindow() { LogInfoWindow.ShowLogInfo(); }
        private bool IsSupportCreateTypeLinkType => CreateType.IsSupportLinkType();
        [ObservableProperty, NotifyCanExecuteChangedFor(nameof(OpenPickPathWindowCommand),nameof(CreateMkLinkCommand))] private LinkType m_CreateType = LinkType.None;
        [ObservableProperty] private bool m_IsEnableCreateDirectory=true;
        [ObservableProperty]
        private bool m_IsEnableOverwrite=false;
        [ObservableProperty, NotifyCanExecuteChangedFor(nameof(CreateMkLinkCommand))] private string m_LinkPointPath = string.Empty;
        [ObservableProperty, NotifyCanExecuteChangedFor(nameof(CreateMkLinkCommand))] private string m_LinkTargetPath = string.Empty;
        [RelayCommand] public void SetCreateType(LinkType type) => CreateType = type;

        private void InternalCreateMkLink()
        {
            PathType pathType = PathInfo.GetPathType(LinkTargetPath);
            string? lppRoot = Path.GetPathRoot(LinkPointPath);
            string? ltpRoot = Path.GetPathRoot(LinkTargetPath);

            if (string.IsNullOrWhiteSpace(lppRoot) || string.IsNullOrWhiteSpace(ltpRoot))
                throw new ArgumentException($"目录必须都是绝对路径 \r\n[连接点路径:{LinkPointPath}]\r\n[目标路径:{LinkTargetPath}]");

            if (CreateType == LinkType.SYMLINK || pathType != PathType.FileType)
                throw new ArgumentException($"连接类型:[{CreateType}] 与 路径类型:{pathType}, 之间不匹配\r\n文件型符号连接仅支持文件类型的操作！");

            else if (CreateType == LinkType.SYMLINKD && pathType != PathType.DirectoryType)
                throw new ArgumentException($"连接类型:[{CreateType}] 与 路径类型:{pathType}, 之间不匹配\r\n目录型符号连接仅支持目录类型的操作！");

            else if (CreateType == LinkType.JUNCTION && pathType != PathType.DirectoryType)
                throw new ArgumentException($"连接类型:[{CreateType}] 与 路径类型:{pathType}, 之间不匹配\r\n目录联接模式仅支持目录类型的操作！");

            else if (CreateType == LinkType.HardLink && (pathType != PathType.FileType || !lppRoot.Equals(ltpRoot, StringComparison.OrdinalIgnoreCase)))
                throw new ArgumentException($"连接类型:[{CreateType}]， 路径类型:{pathType} \r\n 连接点根目录:{lppRoot} ，目标点根目录:{ltpRoot}]\r\n硬链接只支持文件类型且必须在同一个根目录中");

            ManageCore.CreateLink(CreateType, LinkPointPath, LinkTargetPath, IsEnableCreateDirectory, IsEnableOverwrite);
        }
        private bool AllowCreate => Path.IsPathRooted(LinkPointPath) && Path.Exists(LinkTargetPath) && CreateType.IsSupportLinkType();
        [RelayCommand(CanExecute = nameof(AllowCreate))] public void CreateMkLink()
        {
            string Mess = $"操作将创建从\r\n{LinkPointPath}\r\n到\r\n{LinkTargetPath}\r\n的连接，是否确认操作?";
            if (MessageBoxEx.Show(mainWindow, Mess, "创建新连接确认", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.Cancel)
                return;
            try
            {
                if (UsersAndPermissionsUtilityTools.OsCurrentUserIsAdministrator() ?? false)
                    InternalCreateMkLink();
                else
                {
                    try
                    {
                        ShellExecuteTools.SystemMklink(CreateType, PathInfo.GetPathType(LinkTargetPath), LinkPointPath, LinkTargetPath);
                        ManageCore.AddRecordData(new RecordData(LinkPointPath));
                    }
                    catch (MklinkException)
                    {
                        try
                        {
                            ShellExecuteTools.SystemMklink(CreateType, LinkPointPath, LinkTargetPath);
                            ManageCore.AddRecordData(new RecordData(LinkPointPath));
                        }
                        catch (Exception ex)
                        {
                            LogManage.WriteExceptionInfo("创建连接错误：", ex);
                            MessageBoxEx.Show(mainWindow, ex.Message, "创建连接错误", MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }
            catch(Exception ex) 
            {
                LogManage.WriteExceptionInfo("创建连接错误：", ex);
                MessageBoxEx.Show(mainWindow, ex.Message, "设置错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            mainWindow.CreateLink.Visibility = Visibility.Hidden;
        }

        private void addregInfo(string ExePate)
        {
            using (RegistryKey CRoot = Registry.ClassesRoot)
            {
                RegistryKey? Project = null, command = null, Project_D = null, command_D = null;
                try
                {
                    Project = CRoot.OpenSubKey("*\\shell\\SymbolicLinkManage", true);
                    if (Project == null)
                        Project = CRoot.CreateSubKey("*\\shell\\SymbolicLinkManage");

                    Project.SetValue(string.Empty, $"新增符号链接到->");
                    Project.SetValue("Icon", $"\"{ExePate}\"");

                    command = Project.OpenSubKey("command", true);
                    if (command == null)
                        command = Project.CreateSubKey("command", true);

                    command.SetValue(string.Empty, $"\"{ExePate}\" \"%1\"");


                    Project_D = CRoot.OpenSubKey("Directory\\shell\\SymbolicLinkManage", true);
                    if (Project_D == null)
                        Project_D = CRoot.CreateSubKey("Directory\\shell\\SymbolicLinkManage");

                    Project_D.SetValue(string.Empty, $"新增符号链接到->");
                    Project_D.SetValue("Icon", $"\"{ExePate}\"");

                    command_D = Project_D.OpenSubKey("command", true);
                    if (command_D == null)
                        command_D = Project_D.CreateSubKey("command", true);

                    command_D.SetValue(string.Empty, $"\"{ExePate}\" \"%1\"");

                }
                catch (Exception exc)
                {
                    LogManage.WriteExceptionInfo("注册系统右键菜单错误：", exc);
                    MessageBoxEx.Show(mainWindow, $"注册系统右键菜单错误:{exc.Message}", "注册失败", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                finally
                {
                    Project?.Close();
                    command?.Close();
                }
            }
        }

        [RelayCommand] public void AddRegInfo()
        {
            try
            {
                string? exePath = System.Diagnostics.Process.GetCurrentProcess()?.MainModule?.FileName;
                if (exePath == null)
                {
                    string[] Exes = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory).Where(p => p.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)).ToArray();
                    if (Exes.Length == 1)
                        exePath = Exes[0];
                    else
                        exePath = Exes.FirstOrDefault(p => Path.GetFileNameWithoutExtension(p).Equals("SymbolicLinkManage", StringComparison.OrdinalIgnoreCase));
                }
                if (string.IsNullOrEmpty(exePath))
                    throw new FileNotFoundException("未找到[SymbolicLinkManage.exe]可执行文件");

                if (UsersAndPermissionsUtilityTools.OsCurrentUserIsAdministrator() ?? false)
                    addregInfo(exePath);
                else
                    ShellExecuteTools.AddregInfo(exePath);
            }
            catch(Exception ex)
            {
                MessageBoxEx.Show(mainWindow, ex.Message,"注册右键失败:",MessageBoxButton.OK,MessageBoxImage.Error);
            }
        }

        public void SetArg(string arg)
        {
            LinkTargetPath = arg;
            mainWindow.CreateLink.Visibility = Visibility.Visible;
        }
    }
}
